package com.tdk.wifidirectserver.ui.main

import android.content.Context
import android.net.nsd.NsdManager
import android.net.nsd.NsdServiceInfo
import android.os.Build
import android.os.Environment
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.tdk.wifidirectserver.MyApplication
import com.tdk.wifidirectserver.bean.MessageBean
import com.tdk.wifidirectserver.nsd.NsdServer
import com.tdk.wifidirectserver.socket.client.Client
import com.tdk.wifidirectserver.socket.server.IServerListener
import com.tdk.wifidirectserver.socket.server.Server
import java.io.File
import java.io.FileInputStream
import java.nio.ByteBuffer

class ConnectedServerViewModel : ViewModel() {
    private val TAG: String = "ConnectedServerViewModel"
    private val isServer = false
    private var server: Server? = null
    private var mTargetClient: Client? = null
    var messageList: MutableList<MessageBean> = mutableListOf()
    var messageListUpdateLiveData: MutableLiveData<Int> = MutableLiveData()
    var socketConnectStatus = MutableLiveData<Boolean>()
    var listener: NsdManager.RegistrationListener? = null
    var chatNsdServer: NsdServer? = null
    var clientList: MutableList<Client> = mutableListOf()
    var serverCreateStatus: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
    var nsdServiceInfo: NsdServiceInfo? = null

    fun startServer() {
        if (!isServer) {
            Log.d(TAG, "startServer: Client is allowed to apply startServer ")
        }
        server = Server()
        server!!.setIServerListener(object : IServerListener {
            override fun onServerCreateSuccess(serverPort: Int) {
                Log.d(TAG, "onServerCreateSuccess: Server is created on port $serverPort")
                serverCreateStatus.postValue(true)
                nsdServiceInfo = NsdServiceInfo().apply {
                    serviceName = "TDK"
                    serviceType = "_wifi._tcp."
                    port = serverPort
                }
            }

            override fun onServerCreateFail(serverPort: Int) {
                Log.d(TAG, "onServerCreateFail: Server is not created on port $serverPort")
                serverCreateStatus.postValue(false)
            }

            override fun onClientConnected(client: Client) {
                Log.d(TAG, "onClientConnected: Client is connected")
                mTargetClient = client
                clientList.add(client)
                Log.d(TAG, "onClientConnected: Client list size is ${clientList.size} $clientList")
                if (clientList.size > 0) {
                    socketConnectStatus.postValue(true)
                }

            }

            override fun onClientDisconnected(client: Client) {
                Log.d(TAG, "onClientDisconnected: Client is disconnected")
                clientList.remove(client)
                if (clientList.size == 0) {
                    socketConnectStatus.postValue(false)
                }
                Log.d(TAG, "onClientDisconnected: $clientList")
            }

            override fun parseData(bytes: ByteArray?, client: Client) {
                Log.d(TAG, "parseData: Data is received from client: ${String(bytes!!)}")
                messageList.add(MessageBean(String(bytes), MessageBean.MESSAGE_RECEIVE))
                messageListUpdateLiveData.postValue(messageList.size)

            }

            override fun onServerAlreadyShutdown(serverPort: Int) {
                Log.d(TAG, "onServerAlreadyShutdown: Server is already shutdown on port $serverPort")
                socketConnectStatus.postValue(false)
            }

        })
        server!!.createServer(null, "mainServer")

    }

    fun closeServer() {
        server?.closeServer()
    }


    fun sengMsg(msg: String) {
        messageList.add(MessageBean(msg, MessageBean.MESSAGE_SEND))
        messageListUpdateLiveData.postValue(messageList.size)
        mTargetClient?.let { server?.sendData(msg, it) }
    }

    fun startNsd() {

        listener = object : NsdManager.RegistrationListener {
            override fun onRegistrationFailed(serviceInfo: NsdServiceInfo?, errorCode: Int) {
                Log.d(TAG, "onRegistrationFailed: Registration failed with error code $errorCode")
            }

            override fun onUnregistrationFailed(serviceInfo: NsdServiceInfo?, errorCode: Int) {
                Log.d(TAG, "onUnregistrationFailed: Unregistration failed   with error code $errorCode")

            }

            override fun onServiceRegistered(serviceInfo: NsdServiceInfo?) {
                Log.d(
                    TAG,
                    "onServiceRegistered: Service registered $serviceInfo"
                )
            }

            override fun onServiceUnregistered(serviceInfo: NsdServiceInfo?) {
                Log.d(
                    TAG,
                    "onServiceUnregistered: Service unregistered  with name ${serviceInfo?.serviceName} and type ${serviceInfo?.serviceType}"
                )
            }

        }
        chatNsdServer = NsdServer()
        if (nsdServiceInfo == null) {
            Log.d(TAG, "startNsd:   chatNsdServer is null ")
        } else {
            chatNsdServer?.registerService(MyApplication.instance as Context, nsdServiceInfo!!, listener!!)
        }

    }

    fun stopNsd() {
        if (chatNsdServer == null || listener == null) {
            Log.d(TAG, "stopNsd: chatNsdServer:[$chatNsdServer] or listener:[$listener] is null")
            return
        }
        chatNsdServer!!.unregister(MyApplication.instance as Context, listener!!)
    }

    fun sendFile() {
        //读取文件流
        val file = File(Environment.getExternalStorageDirectory().toString() + "/Download/TecnoConnectInstaller1.0.1.25.exe")
        val size = file.length()
        val fileInputStream = FileInputStream(file)

        val sizeBuffer = ByteBuffer.allocate(8)
        sizeBuffer.putLong(size)
        val fileName = ByteBuffer.allocate(8)
        fileName.put("TecnoConnectInstaller1.0.1.25.exe".toByteArray(charset = Charsets.UTF_8))
        // 每次获取10240字节
        val buffer = ByteArray(10240)
        // 将sizeBuffer 写入到buffer
        val sizeBufferArray = sizeBuffer.array()
        val fileNameArray = fileName.array()
//        val byteArray = ByteArray(sizeBufferArray.size + fileNameArray.size)
        System.arraycopy(sizeBufferArray, 0, buffer, 0, sizeBufferArray.size)
        System.arraycopy(fileNameArray, 0, buffer, sizeBufferArray.size, fileNameArray.size)
        var fileLength = 0
        while (fileInputStream.read(buffer).also { fileLength = it } != -1) {
            //发送数据
            mTargetClient?.sendData(buffer)
        }
        fileInputStream.close()
    }
}